<template>
  <div id="webgl"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const width = window.innerWidth;
const height = window.innerHeight;

// 创建3D场景对象Scene
const scene = new THREE.Scene();
// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
// 实例化一个透视投影相机对象
let camera = null;

function initRenderer() {
  renderer.setSize(width, height); // 设置three.js渲染区域的尺寸(像素px)
  renderer.setClearColor(0xffffff, 1);
  renderer.render(scene, camera);

  function render() {
    renderer.render(scene, camera); //执行渲染操作
    requestAnimationFrame(render);
  }
  render();
}

function initCamera() {
  camera = new THREE.OrthographicCamera(
    -100 * (width / height),
    100 * (width / height),
    100,
    -100,
    1,
    3000
  );
  // 相机在Three.js三维坐标系中的位置
  // 根据需要设置相机位置具体值
  camera.position.set(0, 0, 100);
  // 相机观察目标指向Threejs 3D空间中某个位置
  camera.lookAt(0, 0, 0); //指向mesh对应的位置
  // 设置相机控件轨道控制器OrbitControls
  const controls = new OrbitControls(camera, renderer.domElement);
  // 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
  controls.addEventListener("change", function () {
    renderer.render(scene, camera); //执行渲染操作
  }); //监听鼠标、键盘事件
}

function initPointLight() {
  const pointLight_top = new THREE.PointLight(0xffffff, 1.0);
  pointLight_top.decay = 0.0;
  pointLight_top.position.set(0, 0, 3000);
  scene.add(pointLight_top);

  const pointLight_right = new THREE.PointLight(0xffffff, 1.0);
  pointLight_right.decay = 0.0;
  pointLight_right.position.set(3000, 0, 0);
  scene.add(pointLight_right);

  const pointLight_left = new THREE.PointLight(0xffffff, 1.0);
  pointLight_left.decay = 0.0;
  pointLight_left.position.set(-3000, 0, 0);
  scene.add(pointLight_left);

  const pointLight_bottom = new THREE.PointLight(0xffffff, 1.0);
  pointLight_bottom.decay = 0.0;
  pointLight_bottom.position.set(0, 0, -3000);
  scene.add(pointLight_bottom);
}

function initAxesHelper() {
  // AxesHelper：辅助观察的坐标系
  const axesHelper = new THREE.AxesHelper(150);
  scene.add(axesHelper);
}

function addCircular() {
  const geometry = new THREE.BufferGeometry(); // 创建一个几何体对象
  const R = 100; // 圆弧半径
  const N = 50; // 分段数量
  const sp = (2 * Math.PI) / N; // 两个相邻点间隔弧度
  // 批量生成圆弧上的顶点数据
  const arr = [];
  for (let i = 0; i < N; i++) {
    const angle = sp * i; // 当前点弧度
    // 以坐标原点为中心，在XOY平面上生成圆弧上的顶点数据
    const x = R * Math.cos(angle);
    const y = R * Math.sin(angle);
    arr.push(x, y, 0);
  }
  // 类型数组创建顶点数据
  const vertices = new Float32Array(arr);
  // 创建属性缓冲区对象
  // 3个为一组，表示一个顶点的xyz坐标
  const attribue = new THREE.BufferAttribute(vertices, 3);
  // 设置几何体attributes属性的位置属性
  geometry.attributes.position = attribue;

  // 线材质
  const material = new THREE.LineBasicMaterial({
    color: 0xff0000, //线条颜色
  });
  // 创建线模型对象   构造函数：Line、LineLoop、LineSegments
  // const line = new THREE.Line(geometry, material);
  const line = new THREE.LineLoop(geometry, material); // 线条模型对象
}

onMounted(() => {
  initCamera();
  initAxesHelper();
  initPointLight();
  initRenderer();
});
</script>
